Expand description
wiremock
provides HTTP mocking to perform black-box testing of Rust applications that
interact with third-party APIs.
It provides mocking of HTTP responses using request matching and response templating.
How to install
Add wiremock
to your development dependencies:
[dev-dependencies]
# ...
wiremock = "0.5"
If you are using cargo-edit
, run
cargo add wiremock --dev
Getting started
use wiremock::{MockServer, Mock, ResponseTemplate};
use wiremock::matchers::{method, path};
#[async_std::main]
async fn main() {
// Start a background HTTP server on a random local port
let mock_server = MockServer::start().await;
// Arrange the behaviour of the MockServer adding a Mock:
// when it receives a GET request on '/hello' it will respond with a 200.
Mock::given(method("GET"))
.and(path("/hello"))
.respond_with(ResponseTemplate::new(200))
// Mounting the mock on the mock server - it's now effective!
.mount(&mock_server)
.await;
// If we probe the MockServer using any HTTP client it behaves as expected.
let status = surf::get(format!("{}/hello", &mock_server.uri()))
.await
.unwrap()
.status();
assert_eq!(status, 200);
// If the request doesn't match any `Mock` mounted on our `MockServer` a 404 is returned.
let status = surf::get(format!("{}/missing", &mock_server.uri()))
.await
.unwrap()
.status();
assert_eq!(status, 404);
}
Matchers
wiremock
provides a set of matching strategies out of the box - check the matchers
module
for a complete list.
You can define your own matchers using the Match
trait, as well as using Fn
closures.
Check Match
’s documentation for more details and examples.
Spying
wiremock
empowers you to set expectations on the number of invocations to your Mock
s -
check the expect
method for more details.
Expectations can be used to verify that a side-effect has (or has not) taken place!
Expectations are automatically verified during the shutdown of each MockServer
instance,
at the end of your test. A failed verification will trigger a panic.
By default, no expectations are set on your Mock
s.
Responses
wiremock
lets you specify pre-determined responses using ResponseTemplate
and
respond_with
.
You also given the option to have Mock
s that return different responses based on the matched
Request
using the Respond
trait.
Check Respond
’s documentation for more details and examples.
Test isolation
Each instance of MockServer
is fully isolated: start
takes care of finding a random port
available on your local machine which is assigned to the new MockServer
.
To ensure full isolation and no cross-test interference, MockServer
s shouldn’t be
shared between tests. Instead, MockServer
s should be created in the test where they are used.
When a MockServer
instance goes out of scope (e.g. the test finishes), the corresponding
HTTP server running in the background is shut down to free up the port it was using.
Runtime compatibility
wiremock
can be used (and it is tested to work) with both async_std
and tokio
as
futures runtimes.
If you encounter any compatibility bug, please open an issue on our GitHub repository.
Efficiency
wiremock
maintains a pool of mock servers in the background to minimise the number of
connections and the time spent starting up a new MockServer
.
Pooling reduces the likelihood of you having to tune your OS configurations (e.g. ulimit).
The pool is designed to be invisible: it makes your life easier and your tests faster. If you end up having to worry about it, it’s a bug: open an issue!
Prior art
mockito
and httpmock
provide HTTP mocking for Rust.
Check the table below to see how wiremock
compares to them across the following dimensions:
- Test execution strategy (do tests have to be executed sequentially or can they be executed in parallel?);
- How many APIs can I mock in a test?
- Out-of-the-box request matchers;
- Extensible request matching (i.e. you can define your own matchers);
- Sync/Async API;
- Spying (e.g. verify that a mock has/hasn’t been called in a test);
- Standalone mode (i.e. can I launch an HTTP mock server outside of a test suite?).
Test execution strategy | How many APIs can I mock? | Out-of-the-box request matchers | Extensible request matching | API | Spying | Standalone mode | |
---|---|---|---|---|---|---|---|
mockito | ❌ Sequential | ❌ 1 | ✔ | ❌ | Sync | ✔ | ❌ |
httpmock | ✔ Parallel | ✔ Unbounded | ✔ | ✔ | Async/Sync | ✔ | ✔ |
wiremock | ✔ Parallel ️ | ✔ Unbounded | ✔ | ✔ | Async | ✔ | ❌ |
Future evolution
More request matchers can be added to those provided out-of-the-box to handle common usecases.
Related projects
stubr
for mountingWiremock
json stubs in aMockServer
. Also works as a cli.
Modules
- Convenient re-exports of
http-types
’ types that are part ofwiremock
’s public API. - A collection of different matching strategies provided out-of-the-box by
wiremock
.
Structs
- Given a set of matchers, a
Mock
instructs an instance ofMockServer
to return a pre-determined response if the matching conditions are satisfied. - A fluent builder to construct a
Mock
instance given matchers and aResponseTemplate
. - You get a
MockGuard
when registering a scopedMock
usingMockServer::register_as_scoped
orMock::mount_as_scoped
. - An HTTP web-server running in the background to behave as one of your dependencies using
Mock
s for testing purposes. - A builder providing a fluent API to assemble a
MockServer
step-by-step.
UseMockServer::builder
to get started. - An incoming request to an instance of
MockServer
. - The blueprint for the response returned by a
MockServer
when aMock
matches on an incoming request.